
# GeneticStarFighter.rb
# The game engine.

require 'yaml'
require 'libs/gosu'

require 'game/Player'
require 'game/Enemy'
require 'game/Bullet'

class GeneticStarFighter < Gosu::Window

  def initialize(settings={})
    super(800, 600, false)

    @font = Gosu::Font.new(self, Gosu::default_font_name, 20)
    @background_image = Gosu::Image.new(self, settings['background'], true)
    self.caption      = "Genetic Star Fighter v0.1-alpha"

    @settings  = settings
    @wins      = @loses = 0
    @round     = 1
    @game_over = false
    create_world
  end	  

  # Cleans the environment in order to start another round.
  def clean_world
    unless @last_shooter.nil?	
      @last_shooter.inc_stat(:victory) unless @last_shooter.out?		
    end

    @enemies.each do |enemy| 
      enemy = @last_shoter if enemy == @last_shoter 
    end

    @player.destroy
    @player.show_briefing

    @enemies.each do |enemy| 
      enemy.destroy
      enemy.show_briefing
    end

    @round += 1
    sleep(3)
  end

  # Creates a new environment for another round.
  def create_world
    @last_shooter = nil
    @enemy_count  = @settings['enemy_count']
    @enemies      = []

    @enemy_count.times do
      enemy = Enemy.new(self, @settings['fighter']['enemy'])
      @enemies.push(enemy)
      enemy.place((rand * 800) + 20, (rand * 600) + 10)
    end
    
    @player = Player.new(self, @settings['fighter']['player'])
    @player.place(400, 300)
  end

  def update

    @enemies.each do |enemy| 
      if enemy.out? and enemy.alive
        enemy.destroy 
        @enemy_count -= 1
      end
    end
    
    if @player.out?			
      puts "Player dead, you lose!"
      @loses += 1
      clean_world
      create_world
    end
    
    if @enemy_count == 0	
      puts "All enemies dead, you win!"
      @wins += 1
      clean_world
      create_world
    end

    # Define the keyboard input.
    @player.turn_left  if button_down? Gosu::Button::KbLeft 
    @player.turn_right if button_down? Gosu::Button::KbRight
    @player.accelerate if button_down? Gosu::Button::KbUp
    
    # Look if the player has shoot to any enemy, and perform the actions needed.
    @player.bullets.each do |bullet|
      @enemies.each do |enemy|
        if bullet.collision?(enemy)
          bullet.destroy
          enemy.react_to(bullet)
          @player.inc_stat(:produced)
        end
      end
    end

    # Look if the enemies have shoot the player, and perform the actions needed.
    @enemies.each do |enemy|
      enemy.bullets.each do |bullet|
      	if bullet.collision?(@player)
          @last_shooter = enemy
          bullet.destroy
          @player.react_to(bullet)
          enemy.inc_stat(:produced, :positive)
        end
      end
    end
    
    # Look if the enemies have shoot to themselves, and perform the actions 
    # needed.
    @enemies.each do |enemy|
      enemy.bullets.each do |bullet|
        @enemies.each do |friend|
          if enemy != friend && bullet.collision?(friend)
            bullet.destroy
            friend.react_to(bullet)
            enemy.inc_stat(:produced, :negative)
          end
      	end
      end
    end

    # Perform the enemy's actions.
    @enemies.each do |enemy|
      $player = @player
      enemy.actions
    end    
    
    @player.direct_motion
    @enemies.each { |enemy| enemy.direct_motion }
  end
  
  def draw
    @background_image.draw(0, 0, 0)
    @player.draw
    @enemies.each { |enemy| enemy.draw }
    @font.draw("Round #{@round}", 10, 10, 0, 1.0, 1.0, 0xffffff00)
  end

  def button_down(id)
    if id == Gosu::Button::KbEscape
      puts "Game Over"
      puts "Rounds won : #{@wins}"
      puts "Rounds lost: #{@loses}"

      close
    end
  end
  
  def button_up(id)
    if id == Gosu::Button::KbSpace
      @player.shoot
    end
  end

end

settings = YAML.load(File.open("config/settings.yml", "r"))
GeneticStarFighter.new(settings).show
